package ProxyClient;

import java.io.File;
import java.util.HashMap;

public class HttpProxy implements IHttpDownloader{
	private static final String	URL_DELIMETER = "__";
	private static final String CACHE_FOLDER  = "cache";

	protected HttpDownloader httpDownloader;
	protected HashMap<String, HttpResource> resourcesCache;
	
	static{
		/** if there is no cache folder, create one **/
		if(!FileUtil.pathExists(CACHE_FOLDER)) {
			boolean dirCreated = FileUtil.createDirectory(CACHE_FOLDER);
			if (!dirCreated) {
		    	System.out.println("Directory creation failed");
			}
		}
	}

	public HttpProxy(){
		httpDownloader = new HttpDownloader();
		resourcesCache = new HashMap<String, HttpResource>();
	}
	
	public HttpResource getResource(String url) {
		HttpResource resource = null;
		String fileKey = urlToFileKey(url);
		/** Check the in-memory cache **/
		if (isCached(url)) {
			resource = getFromCache(url);
			System.out.println("The following request extracted from memory cache: "+url);
		}
		/** Check for the file in the filesystem cache **/
		else if (FileUtil.pathExists(CACHE_FOLDER+"/"+fileKey)) {
			if (HttpDownloader.isSupportedMediaFormat(url)) {
				byte[] contentsBytes = FileUtil.readFile(CACHE_FOLDER+"/"+fileKey);
				resource = new HttpResource(url, contentsBytes);
			} else {
				String contents = FileUtil.getFileContents(CACHE_FOLDER+"/"+fileKey);
				resource = new HttpResource(url, contents);
			}
			/** Cache the resource in memory **/
			putInCache(url, resource);
			System.out.println("The following request extracted from file cache: "+url);
		}
		else {
			/** Download the resource **/
			resource = httpDownloader.getResource(url);
			/** Cache the resource in memory **/
			putInCache(url, resource);
			/** Cache the resource in the file system **/	
			if (resource.getIsMedia()) {
				FileUtil.saveFile(CACHE_FOLDER+"/"+fileKey, resource.getBinaryData());
			} else {
				FileUtil.saveFile(CACHE_FOLDER+"/"+fileKey, resource.getContents());
			}
			System.out.println("The following request was downloaded and put in cache: "+url);
		}
		return resource;
	}
	
	protected static String urlToFileKey(String url) {
		if(!HttpDownloader.isSupportedMediaFormat(url))
			url+=".cache";
		return url.replace("http://", "").replace("/", URL_DELIMETER);
	}
	
	protected static String fileKeyToUrl(String key) {
		return "http://"+key.replace(URL_DELIMETER, "/").replace(".cache", "");
	}
	
	protected void putInCache(String key, HttpResource resource) {
		resourcesCache.put(key, resource);
	}
	
	protected HttpResource getFromCache(String key) {
		return resourcesCache.get(key);
	}
	
	protected boolean isCached(String key) {
		return resourcesCache.containsKey(key);
	}
}
